#ifndef _workdir_filesystem_Abstract_h
#define _workdir_filesystem_Abstract_h

#include <vector>
#include <string>

#include <nemesis.ExclusiveHash.h>

namespace workdir {

namespace filesystem {

using namespace nemesis;

class Abstract {
public:
   struct ClassType { enum _v { Directory, File }; };
   
   typedef std::vector <Abstract*> child_container;
   typedef child_container::iterator child_iterator;
   typedef child_container::const_iterator const_child_iterator;
   
   virtual ~Abstract ();
   
   Abstract* getParent () const throw () { return a_parent; }
   ClassType::_v getClassType () const throw () { return a_classType; }
   const std::string& getName () const throw () { return a_name; }
   const std::string& getPath () const throw () { return a_path; }

   int child_size () const throw () { return a_children.size (); }
   
   child_iterator child_begin () throw () { return a_children.begin (); }
   child_iterator child_end () throw () { return a_children.end (); }   
   static Abstract* child (child_iterator ii) throw () { return *ii; }

   const_child_iterator child_begin () const throw () { return a_children.begin (); }
   const_child_iterator child_end () const throw () { return a_children.end (); }   
   static const Abstract* child (const_child_iterator ii) throw () { return *ii; }
   
   static std::string calculePath (const Abstract* parent, const std::string& shortPath) throw ();
   
   virtual void print (const int level) const throw () = 0;

protected:
   Abstract (const ClassType::_v, const std::string& name);
   Abstract (const ClassType::_v, Abstract* parent, const std::string& name);
   
private:
   const ClassType::_v a_classType;
   Abstract* a_parent;   
   const std::string a_name;
   std::string a_path;
   child_container a_children;
   
   Abstract (const Abstract&);
};

}
}

#endif
